package com.jeesite.modules.isys.common.aop.query;


import com.alibaba.fastjson2.util.DateUtils;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jeesite.common.lang.StringUtils;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

@Component
public class QueryUtils {

    @Autowired
    private NullExec nullExec;

    public QueryWrapper getQueryWrapper(Object object) throws IllegalAccessException {
      object =   nullExec.execObjNull(object);

            QueryWrapper queryWrapper = new QueryWrapper();

            if (object != null) {
                //判断是否应该阶段该对象
                if (checkSearchObj(object)) {
                Field[] declaredFields = object.getClass().getDeclaredFields();
                for (Field field : declaredFields) {
                    field.setAccessible(true);

                    //跳过serialVersionUID
                    if (field.getName().equals("serialVersionUID")) {
                        continue;
                    }

                    //获取值
                    Object value = field.get(object);

                    //值为空，不继续走
                    if (value == null) {
                        continue;
                    }

                    //获取到查询注解
                    Search annotation = field.getAnnotation(Search.class);

                    //有注解
                    if (annotation != null) {
                        //判断是否查询
                        boolean search = annotation.search();

                        if (search) {
                            //获取到查询类型
                            SearchTpype type = annotation.type();

                            //获取到属性对应的表字段名
                            String tableField = getTableField(field);


                            //相等查询
                            if (type == SearchTpype.EQUAL) {
                                queryWrapper.eq(tableField, value);
                            }

                            //相似查询
                            if (type == SearchTpype.LIKE) {

                                //获取相似查询的模式字符串
                                String pattern = annotation.pattern();

                                //替换模式字符串
                                pattern = pattern.replaceAll("#arg#", String.valueOf(value));

                                //进行查询
//                            queryWrapper.like(true,value,pattern);
                                queryWrapper.apply(tableField + " like " + pattern);
                            }
                        }
                    } else {
                        //没注解


                        //判断是否为基础类型

                        //获取到属性对应的表字段名
                    String tableField = getTableField(field);

                    queryWrapper.eq(tableField,value);

                    }



                }
            }


        }
        return queryWrapper;
    }

    private boolean checkSearchObj(Object object) {

        if (object == null){
            return  false;
        }
        SearchObj annotation = object.getClass().getAnnotation(SearchObj.class);
        if (annotation == null){
            return false;
        }

        return true;
    }

    private String getTableField(Field field){
        String fieldName = null;
        TableField annotation = field.getAnnotation(TableField.class);
        if (annotation == null){
            fieldName =  TableFieldUtils.propertyToField(field.getName());
        }else {
            fieldName = annotation.value();
        }

        return fieldName;
    }


    public String buildQueryWhereLambdaQueryWrapper(LambdaQueryWrapper queryWrapper){
        if (queryWrapper == null){
            return null;
        }

        //逻辑删除
        queryWrapper.last("deleted = 0");
        String customSqlSegment = queryWrapper.getCustomSqlSegment();

        if (customSqlSegment == null){
            return  null;
        }
        Set<Map.Entry> set = queryWrapper.getParamNameValuePairs().entrySet();
        for (Map.Entry entry : set) {
            customSqlSegment = customSqlSegment.replace("#{ew.paramNameValuePairs." + entry.getKey() + "}", formatParamValue(entry.getValue()));
        }
        return customSqlSegment;
    }

    public String buildQueryWhere(QueryWrapper queryWrapper){
        if (queryWrapper == null){
            return null;
        }

        //逻辑删除
        queryWrapper.eq("deleted",0);

        String customSqlSegment = queryWrapper.getCustomSqlSegment();


        if (customSqlSegment == null){
            return  null;
        }
        Set<Map.Entry> set = queryWrapper.getParamNameValuePairs().entrySet();
        for (Map.Entry entry : set) {
            customSqlSegment = customSqlSegment.replace("#{ew.paramNameValuePairs." + entry.getKey() + "}", formatParamValue(entry.getValue()));
        }
        return customSqlSegment;
    }

    public  String formatParamValue(Object arg) {
        String paramValue;
        if (arg instanceof String) {
            paramValue = "'" + arg.toString().replace("'", "\\'") + "'";
        } else if (arg instanceof Date) {
            paramValue = "'" + DateUtils.format((Date) arg, "yyyy-MM-dd HH:mm:ss") + "'";
        } else if (arg != null) {
            paramValue = arg.toString();
        } else {
            paramValue = null;
        }
        return paramValue;
    }


    //获取到当前需要添加到后面的条件
    public String getQuerySearchWhere(Object object) throws IllegalAccessException {
        QueryWrapper queryWrapper = getQueryWrapper(object);
        if (queryWrapper == null){
            return null;
        }

        String sql = buildQueryWhere(queryWrapper);

        if (sql == null){
            return null;
        }


        String[] split = sql.split("WHERE");

        if (split.length > 1){
            //有内容
            String str = split[1];
            String substring = str.substring(2, str.length() - 1);
            return substring ;
        }


        return null;
    }


    public static String trimBothEndsChars(String srcStr, String splitter) {
        String regex = "^" + splitter + "*|" + splitter + "*$";
        return srcStr.replaceAll(regex, "");
    }
}
